package client.controller;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import javax.media.j3d.Transform3D;
import javax.vecmath.Quat4d;
import javax.vecmath.Vector3d;

import server.controller.ServerObject3DController;

import com.sun.j3d.utils.universe.ViewingPlatform;

import client.Client;
import client.model.Viewpoint3D;
import client.presentation.Viewpoint3DPresentation;

public class Viewpoint3DController implements Virtual3DController{
	
	private Viewpoint3D abstraction;
	private Viewpoint3DPresentation presentation;
	private Universe3DController universe;
	
	public Viewpoint3DController(String n, Vector3d v, Quat4d q, String vrml) {
		presentation = new Viewpoint3DPresentation(this, vrml);
		abstraction = new Viewpoint3D(n, v, q, vrml);
	}
	
	public void setUniverse(Universe3DController u) {
		universe = u;
	}

	public String getName() {
		return abstraction.getName();
	}
	
	public String getFile() {
		return abstraction.getFile();
	}

	public void setOrientation(Quat4d q) {
		if (!q.equals(abstraction.getOrientation())) {
			abstraction.setOrientation(q);
			try {
				ServerObject3DController c = (ServerObject3DController) Naming.lookup(Client.lookupName+"/"+abstraction.getName());
				c.setOrientation(q);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (RemoteException e) {
				e.printStackTrace();
			} catch (NotBoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public Quat4d getOrientation() {
		return abstraction.getOrientation();
	}

	public void setPosition(Vector3d v) {
		if (!v.equals(abstraction.getPosition())) {
			abstraction.setPosition(v);
			try {
				ServerObject3DController c = (ServerObject3DController) Naming.lookup(Client.lookupName+"/"+abstraction.getName());
				c.setPosition(v);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (RemoteException e) {
				e.printStackTrace();
			} catch (NotBoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public Vector3d getPosition() {
		return abstraction.getPosition();
	}

	public void setPresentation(Object p) {
		presentation = (Viewpoint3DPresentation) p;
	}
	
	public Object getPresentation() {
		return presentation;
	}

	public void update(Vector3d position, Quat4d orientation) {
		abstraction.setPosition(position);
		abstraction.setOrientation(orientation);
		Transform3D transform = new Transform3D();
		transform.set(abstraction.getOrientation(), abstraction.getPosition(), 1);
		presentation.setTransform(transform);
		presentation.update();
	}

	public Transform3D getTransform() {
		Transform3D t = new Transform3D();
		t.set(abstraction.getOrientation(), abstraction.getPosition(), 1);
		return t;
	}

	public void setTransform(Transform3D t) {
		Vector3d position = new Vector3d();
		Quat4d orientation = new Quat4d();
		
		t.get(position);
		t.get(orientation);
		
		if (!position.equals(abstraction.getPosition())) {
			try {
				ServerObject3DController c = (ServerObject3DController) Naming.lookup(Client.lookupName+"/"+abstraction.getName());
				c.setPosition(position);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (RemoteException e) {
				e.printStackTrace();
			} catch (NotBoundException e) {
				e.printStackTrace();
			}
		}
		
		if (!orientation.equals(abstraction.getOrientation())) {
			try {
				ServerObject3DController c = (ServerObject3DController) Naming.lookup(Client.lookupName+"/"+abstraction.getName());
				c.setOrientation(orientation);
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (RemoteException e) {
				e.printStackTrace();
			} catch (NotBoundException e) {
				e.printStackTrace();
			}
		}
	}
	
	public ViewingPlatform getViewingPlatform() {
		return universe.getViewingPlatform();
	}

}
